package com.sky.service.userImpl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.OrdersSubmitDTO;
import com.sky.entity.AddressBook;
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.entity.ShoppingCart;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.Orders_DetailMapper;
import com.sky.mapper.ShoppingCartMapper;
import com.sky.properties.BaiduLocationProperties;
import com.sky.service.OrdersService;
import com.sky.service.impl.WebSocketServer;
import com.sky.utils.HttpClientUtil;
import com.sky.vo.OrderDetailsVO;
import com.sky.vo.OrderPageVO;
import com.sky.vo.OrderSubmitVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
@Slf4j
public class OrdersServiceImpl implements OrdersService {
    private static double EARTH_RADIUS = 6378137;
    @Autowired
    AddressBookService addressBookService;

    @Autowired
    ShoppingCartService shoppingCartService;

    @Autowired
    ShoppingCartMapper shoppingCartMapper;

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    Orders_DetailMapper orders_detailMapper;

    @Autowired
    BaiduLocationProperties baiduLocationProperties;

    @Autowired
    WebSocketServer webSocketServer;

    @Override
    /**添加订单*/
    @Transactional
    public OrderSubmitVO addOrder(OrdersSubmitDTO submitDTO) throws IOException {
        //判断地址栏是否为空
        AddressBook addressBook = addressBookService.getById(submitDTO.getAddressBookId());
        if(addressBook == null)
        {throw new DeletionNotAllowedException(MessageConstant.ADDRESS_BOOK_IS_NULL);}

        //判断购物是否为空
        List<ShoppingCart> shoppingCarts = shoppingCartService.queryShoppingCart();
        if(shoppingCarts == null || shoppingCarts.size() == 0){
            throw new DeletionNotAllowedException(MessageConstant.SHOPPING_CART_IS_NULL);}



        HashMap shopMap = new HashMap();

        shopMap.put("address",baiduLocationProperties.getAddress());
        shopMap.put("output","json");
        shopMap.put("ak",baiduLocationProperties.getAK());

        String result = HttpClientUtil.doGet(baiduLocationProperties.getURL(), shopMap);
        JSONObject jsonObject = JSONObject.parseObject(result);

        String shopLng = jsonObject.getJSONObject("result").getJSONObject("location").getString("lng");//经度
        String shopLat = jsonObject.getJSONObject("result").getJSONObject("location").getString("lat");//纬度
        //
        HashMap userMap = new HashMap();

        userMap.put("address",addressBook.getProvinceName()
                +addressBook.getCityName()
                +addressBook.getDistrictName()
                +addressBook.getDetail());
        userMap.put("output","json");
        userMap.put("ak", baiduLocationProperties.getAK());

        String result1 = HttpClientUtil.doGet(baiduLocationProperties.getURL(), userMap);
        JSONObject jsonObject1 = JSONObject.parseObject(result1);

        String userLng = jsonObject1.getJSONObject("result").getJSONObject("location").getString("lng");//经度
        String userLat = jsonObject1.getJSONObject("result").getJSONObject("location").getString("lat");//纬度


        double ulat = Double.valueOf(userLng)*Math.PI/180.0;
        double slat = Double.valueOf(shopLng)*Math.PI/180.0;

        double lng = (Double.valueOf(shopLng) - Double.valueOf(userLng)) * Math.PI / 180.0;
        double lat = (Double.valueOf(shopLat) - Double.valueOf(userLat)) * Math.PI / 180.0;

        Double lng1 = Math.sin(lng/2.0);
        Double lat1 = Math.sin(lat/2.0);

        Double distance = 2 * EARTH_RADIUS * Math.asin(Math.sqrt(lat1*lat1+Math.cos(ulat)*Math.cos(slat)*lng1*lng1));
        System.out.println(distance);

        if(distance > 5000.0){
            throw new DeletionNotAllowedException(MessageConstant.DISTANCE_TOO_FAR);//距离太远不送
        }

        //创建Orders,并准备数据
        Orders orders = new Orders();
        BeanUtils.copyProperties(submitDTO,orders);
        orders.setUserId(BaseContext.getCurrentId());
        orders.setOrderTime(LocalDateTime.now());
        orders.setPayStatus(Orders.UN_PAID);
        orders.setCheckoutTime(LocalDateTime.now());
        orders.setPhone(addressBook.getPhone());
        orders.setAddress(addressBook.getProvinceName()
                        +addressBook.getCityName()
                        +addressBook.getDistrictName()
                        +addressBook.getDetail());
        orders.setConsignee(addressBook.getConsignee());
        orders.setNumber(String.valueOf(System.currentTimeMillis()));
        orders.setStatus(Orders.PENDING_PAYMENT);

        //将准备好的数据导入数据库
        orderMapper.insertOrder(orders);

        //创建order_detail对象,并准备数据
        List<OrderDetail> orderDetails = new ArrayList<>();
        for (ShoppingCart shoppingCart : shoppingCarts) {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOrderId(orders.getId());
            orderDetail.setAmount(shoppingCart.getAmount());
            if (shoppingCart.getDishFlavor() != null) {
                orderDetail.setDishFlavor(shoppingCart.getDishFlavor());
            }
            orderDetail.setImage(shoppingCart.getImage());
            if(shoppingCart.getDishId() != null){
                orderDetail.setDishId(shoppingCart.getDishId());
            }
            orderDetail.setNumber(shoppingCart.getNumber());
            orderDetail.setName(shoppingCart.getName());
            if(shoppingCart.getSetmealId() != null){
                orderDetail.setSetmealId(shoppingCart.getSetmealId());
            }
            orderDetails.add(orderDetail);
        }
        //将准备好的数据导入数据库
        orders_detailMapper.insertOrdersDetail(orderDetails);

        //清空该用户的购物车
        shoppingCartMapper.deleteAll(orders.getUserId());

        OrderSubmitVO submitVO = new OrderSubmitVO();

        submitVO.setOrderTime(orders.getOrderTime());
        submitVO.setId(orders.getId());
        submitVO.setOrderNumber(orders.getNumber());
        submitVO.setOrderAmount(orders.getAmount());

        HashMap map = new HashMap();
        map.put("type",1);
        map.put("orderId",orders.getId());
        map.put("content","订单号:"+orders.getNumber());
        webSocketServer.sendToAllClient(JSON.toJSONString(map));

        return submitVO;
    }

    @Override
    @Transactional
    public OrderDetailsVO selectById(Long id) {
        //判空
        if(id == null){throw new DeletionNotAllowedException(MessageConstant.ID_IS_NULL);}
        //查询订单
        Orders orders = orderMapper.selectOrderById(id);
        //查询详情订单
        List<OrderDetail> orderDetails = orders_detailMapper.selectOrederDetailById(id);

        OrderDetailsVO orderDetailsVO = new OrderDetailsVO();
        BeanUtils.copyProperties(orders,orderDetailsVO);
        orderDetailsVO.setOrderDetailList(orderDetails);

        return orderDetailsVO;
    }

    @Override
    /**历史订单查询*/
    @Transactional
    public OrderPageVO QueryHistoryOrderDetail(Integer page, Integer pageSize, Integer status) {
        OrderPageVO orderPageVO = new OrderPageVO();

        Page<OrderDetailsVO> detailsVOList;

        PageHelper.startPage(page,pageSize);

        detailsVOList = orderMapper.selectOrderByUserId(BaseContext.getCurrentId(),status);

        for (OrderDetailsVO order : detailsVOList) {
            List<OrderDetail> orderDetailList = orders_detailMapper.selectOrederDetailById(order.getId());
            order.setOrderDetailList(orderDetailList);
        }

        orderPageVO.setRecords(detailsVOList.getResult());

        orderPageVO.setTotal(detailsVOList.getTotal());

        return orderPageVO;
    }
/**取消订单*/
//该功能还未实现,还待研发
    @Override
    public void cancelOrderById(Long id) {


        Long userId = BaseContext.getCurrentId();

        orderMapper.cancelOrderById(id,userId,Orders.CANCELLED);
    }

    /**催单*/
    @Override
    public void reminderOrder(Long id) {
        if(id == null){throw new DeletionNotAllowedException(MessageConstant.ID_IS_NULL);}

        Orders orders = orderMapper.selectOrderById(id);

        if(orders == null){
            throw new DeletionNotAllowedException(MessageConstant.ORDER_REMDER);
        }

        HashMap map = new HashMap();
        map.put("type",2);
        map.put("orderId",id);
        map.put("content","订单号:"+orders.getNumber());
        log.info("催单");
        webSocketServer.sendToAllClient(JSON.toJSONString(map));

    }
/**再来一单*/
    @Override
    public void OnceAgain(Long id) {
        List<OrderDetail> orderDetails = orders_detailMapper.selectOrederDetailById(id);

        ShoppingCart shoppingCart = new ShoppingCart();

        for (OrderDetail orderDetail : orderDetails) {
            if(orderDetail.getDishId() != null){
                shoppingCart.setDishId(orderDetail.getDishId());
            }else {
                shoppingCart.setSetmealId(orderDetail.getSetmealId());
            }
            shoppingCart.setName(orderDetail.getName());
            shoppingCart.setCreateTime(LocalDateTime.now());
            shoppingCart.setUserId(BaseContext.getCurrentId());
            shoppingCart.setAmount(orderDetail.getAmount());
            shoppingCart.setImage(orderDetail.getImage());
            if(orderDetail.getDishFlavor() != null){
                shoppingCart.setDishFlavor(orderDetail.getDishFlavor());
            }

            List<ShoppingCart> shoppingCarts = shoppingCartService.queryShoppingCart();
            if(shoppingCarts != null && shoppingCarts.size() > 0) {
                shoppingCarts.forEach(s -> {
                    if (s.getDishId() != null && s.getDishId() == orderDetail.getDishId()) {
                        s.setNumber(s.getNumber() + 1);
                        shoppingCart.setNumber(s.getNumber());
                    }
                    shoppingCart.setNumber(1);
                });
            }else {shoppingCart.setNumber(1);}

            shoppingCartMapper.insertShopCart(shoppingCart);
        }
    }
}
